package com.fourpigeon.service.impl;

import com.fourpigeon.dao.*;
import com.fourpigeon.domain.*;
import com.fourpigeon.service.BlogGetService;
import com.fourpigeon.utils.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.fourpigeon.utils.RedisConstants.*;

//
@Service("blogGetService")
public class BlogGetServiceImpl extends BlogServiceImpl implements BlogGetService {
    @Autowired
    private BlogDailyDao blogDailyDao;
    @Autowired
    private BlogDealDao blogDealDao;
    @Autowired
    private BlogPracticeDao blogPracticeDao;
    @Autowired
    private BlogAgreeDao blogAgreeDao;
    @Autowired
    private BlogCommentDao blogCommentDao;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 根据id查询日常贴
     * @param blogId 博客id
     * @return blogDaily对象
     */
    @Override
    public Result getDaily(Long blogId) {
        BlogDaily blogDaily = searchBlog(BLOG_TTL_KEY+"daily:",blogId,BlogDaily.class,(id) -> blogDailyDao.getById(id));
        if (blogDaily == null) {
            return Result.fail("该贴子不存在!");
        }
        //判断是否点赞
        blogDaily.setLike(likeOrNot(blogId));
        //处理图片临时链接
        blogDaily.handlerImgs();
        //返回结果
        return Result.ok(blogDaily);
    }

    /**
     * 根据id查询交易贴
     * @param blogId 博客id
     * @return 结果信息
     */
    @Override
    public Result getDeal(Long blogId) {
        BlogDeal blogDeal = searchBlog(BLOG_TTL_KEY+"deal:",blogId,BlogDeal.class,(id) -> blogDealDao.getById(id));
        if (blogDeal == null) {
            return Result.fail("该贴子不存在!");
        }
        //处理贴子图片临时链接
        blogDeal.handlerImgs();
        return Result.ok(blogDeal);
    }

    /**
     * 根据id查询约球贴信息
     * @param blogType 博客类型
     * @param blogId 博客id
     * @return 结果信息
     */
    @Override
    public Result getAgree(Short blogType, Long blogId) {
        if (!agreeGetMap.containsKey(blogType)) {
            return Result.fail("该贴子不存在!");
        }
        BlogAgree blogAgree = agreeGetMap.get(blogType).apply(blogId);
        if (blogAgree == null) {
            return Result.fail("该贴子不存在!");
        }
        //处理贴子图片临时链接
        blogAgree.handlerImgs();
        return Result.ok(blogAgree);
    }

    /**
     * 根据id查询陪教贴信息
     * @param blogId 博客id
     * @return 结果信息
     */
    @Override
    public Result getPractice(Long blogId) {
        BlogPractice blogPractice = searchBlog(BLOG_TTL_KEY+"practice:",blogId,BlogPractice.class,(id) -> blogPracticeDao.getById(id));
        if (blogPractice == null) {
            return Result.fail("该贴子不存在!");
        }
        //处理贴子图片临时链接
        blogPractice.handlerImgs();
        return Result.ok(blogPractice);
    }

    /**
     * 日常贴分页查询
     * @param startId 起始id
     * @return 结果信息
     */
    @Override
    public Result getDailys(Long startId) {
        //分页查询传入0时默认读取最新(最迟创建)数据，进行处理
        long sId = zeroHandler(startId);
        List<BlogDaily> list = blogDailyDao.getDailys(sId);
        //查询是否点赞
        for (BlogDaily blogDaily : list) {
            blogDaily.setLike(likeOrNot(blogDaily.getId()));
            //处理贴子图片临时链接
            blogDaily.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 评论分页查询
     * @param blogId 博客id
     * @return 结果信息
     */
    @Override
    public Result getPageComment(Long blogId,Long start) {
        //处理0
//        int startId = zeroHandler(start);
        List<BlogComment> list = blogCommentDao.getPageByBlogId(blogId, start);
        //TODO 查询是否点赞
        for (BlogComment blogComment : list) {
            blogComment.setLike(likeOrNotCom(blogComment.getId()));
            blogComment.handlerImgs();
        }
        //返回结果以及长度
        return Result.ok(list,((Integer)(list.size())).longValue());
    }

    /**
     * 交易贴分页查询
     * @param startId 开始id
     * @return 结果信息
     */
    @Override
    public Result getDeals(Long startId) {
        //分页查询传入0时默认读取最新(最迟创建)数据，进行处理
        startId = zeroHandler(startId);
        List<BlogDeal> list = blogDealDao.getDailys(startId);
        for (BlogDeal blogDeal : list) {
            //处理贴子图片临时链接
            blogDeal.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 约球贴分页查询
     * @param blogType 博客类型
     * @param startId 开始id
     * @return 结果信息
     */
    @Override
    public Result getAgrees(Short blogType,Long startId) {
        //分页查询传入0时默认读取最新(最迟创建)数据，进行处理
        startId = zeroHandler(startId);
        List<BlogAgree> list = agreeGetsMap.get(blogType).apply(startId);
        for (BlogAgree blogAgree : list) {
            //处理贴子图片临时链接
            blogAgree.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 陪教贴分页查询
     * @param startId 开始id
     * @return 结果信息
     */
    @Override
    public Result getPractices(Long startId) {
        //分页查询传入0时默认读取最新(最迟创建)数据，进行处理
        startId = zeroHandler(startId);
        List<BlogPractice> list = blogPracticeDao.getPractices(startId);
        for (BlogPractice blogPractice : list) {
            //处理贴子图片临时链接
            blogPractice.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 根据约球帖类型和用户id查询用户约球帖
     * @param blogType 约球帖类型
     * @param userId 用户id
     * @return 结果信息
     */
    @Override
    public Result getUserAgrees(Short blogType, Long userId, Long startId) {
        startId = zeroHandler(startId);
        List<BlogAgree> list = userAgreeGetsMap.get(blogType).apply(userId, startId);
        for (BlogAgree blogAgree: list) {
            //处理贴子图片临时链接
            blogAgree.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 根据用户id查询日常帖
     * @param userId 用户Id
     * @return 结果信息
     */
    @Override
    public Result getUserDailies(Long userId, Long startId) {
        startId = zeroHandler(startId);
        List<BlogDaily> list = blogDailyDao.getByUserId(userId, startId);
        for (BlogDaily blogDaily : list) {
            blogDaily.setLike(likeOrNot(blogDaily.getId()));
            //处理贴子图片临时链接
            blogDaily.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 根据用户id查询交易帖
     * @param userId 用户Id
     * @return 结果信息
     */
    @Override
    public Result getUserDeals(Long userId, Long startId) {
        startId = zeroHandler(startId);
        List<BlogDeal> list = blogDealDao.getByUserId(userId, startId);
        for (BlogDeal blogDeal : list) {
            //处理贴子图片临时链接
            blogDeal.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 根据用户id查询陪练帖
     * @param userId 用户Id
     * @return 结果信息
     */
    @Override
    public Result getUserPractices(Long userId, Long startId) {
        startId = zeroHandler(startId);
        List<BlogPractice> list = blogPracticeDao.getByUserId(userId, startId);
        for (BlogPractice blogPractice: list) {
            //处理贴子图片临时链接
            blogPractice.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }



    /**
     * 查询热门帖
     * @return 结果信息
     */
    @Override
    public Result getHotBlog(Integer blogType) {
        if(blogType == 0){
            List<BlogDaily> hotBlogs = blogDailyDao.getHotDailies();
            if(hotBlogs==null||hotBlogs.isEmpty()) return Result.ok(null);
            // 根据综合热度指标排序
            hotBlogs.sort(Comparator.comparingDouble(this::dailyHotness).reversed());
            BlogDaily mostHotBlog = hotBlogs.get(0);
            mostHotBlog.setLike(likeOrNot(mostHotBlog.getId()));
            //处理贴子图片临时链接
            mostHotBlog.handlerImgs();
            return Result.ok(mostHotBlog);
        }else if(blogType == 1){
            List<BlogDeal> hotBlogs = blogDealDao.getHotDeal();
            if(hotBlogs==null||hotBlogs.isEmpty()) return Result.ok(null);
            hotBlogs.sort(Comparator.comparingDouble(this::dealHotness).reversed());
            BlogDeal mostHotBlog = hotBlogs.get(0);
            mostHotBlog.handlerImgs();
            return Result.ok(mostHotBlog);
        }else if(blogType == 2){
            List<BlogPractice> hotBlogs = blogPracticeDao.getHotPractice();
            if(hotBlogs==null||hotBlogs.isEmpty()) return Result.ok(null);
            hotBlogs.sort(Comparator.comparingDouble(this::practiceHotness).reversed());
            BlogPractice mostHotBlog = hotBlogs.get(0);
            mostHotBlog.handlerImgs();
            return Result.ok(mostHotBlog);
        }
        return Result.ok();
    }

    /**
     * @param blogDaily 日常帖对象
     * @return 日常帖对象的浏览量
     */
    private Double dailyHotness(BlogDaily blogDaily) {
        Double views = stringRedisTemplate.opsForZSet().score(BLOG_CLICK_KEY + clickMap.get(0), String.valueOf(blogDaily.getId()));
        return views != null ? views : 1;
    }

    /**
     * @param blogDeal 交易帖对象
     * @return 交易帖对象的浏览量
     */
    private Double dealHotness(BlogDeal blogDeal) {
        Double views = stringRedisTemplate.opsForZSet().score(BLOG_CLICK_KEY + clickMap.get(1), String.valueOf(blogDeal.getId()));
        return views != null ? views : 1;
    }

    /**
     * @param blogPractice 陪练帖对象
     * @return 陪练帖对象的浏览量
     */
    private Double practiceHotness(BlogPractice blogPractice) {
        Double views = stringRedisTemplate.opsForZSet().score(BLOG_CLICK_KEY + clickMap.get(2), String.valueOf(blogPractice.getId()));
        return views != null ? views : 1;
    }

    /**
     * 用户搜索查询交易帖
     * @param searchKeyWord 用户输入搜索关键词
     * @param type 交易帖类型
     * @return 结果信息
     */
    @Override
    public Result getSearchDeals(String searchKeyWord, Short type) {
        List<BlogDeal> list = blogDealDao.getSearchDeals(searchKeyWord, type);
        if (type == 3){
            list = blogDealDao.getAllSearchDeals(searchKeyWord);
            for (BlogDeal blogDeal : list) {
                //处理贴子图片临时链接
                blogDeal.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        if(list.isEmpty()){
            list = blogDealDao.getByType(type);
            for (BlogDeal blogDeal : list) {
                blogDeal.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        for (BlogDeal blogDeal : list) {
            blogDeal.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    /**
     * 用户搜索查询日常帖
     * @param searchKeyWord 用户输入搜索关键词
     * @param type 日常帖类型
     * @return 结果信息
     */
    @Override
    public Result getSearchDailies(String searchKeyWord, Short type) {
        List<BlogDaily> list = blogDailyDao.getSearchDailies(searchKeyWord, type);
        if (type == 3){
            list = blogDailyDao.getAllSearchDailies(searchKeyWord);
            for (BlogDaily blogDaily: list) {
                blogDaily.setLike(likeOrNot(blogDaily.getId()));
                //处理贴子图片临时链接
                blogDaily.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        if(list.isEmpty()){
            list = blogDailyDao.getByType(type);
            for (BlogDaily blogDaily: list) {
                blogDaily.setLike(likeOrNot(blogDaily.getId()));
                blogDaily.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        for (BlogDaily blogDaily: list) {
            blogDaily.setLike(likeOrNot(blogDaily.getId()));
            blogDaily.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    @Override
    public Result getSearchPractices(String searchKeyWord, Short type) {
        List<BlogPractice> list = blogPracticeDao.getSearchPractices(searchKeyWord, type);
        if (type == 2){
            list = blogPracticeDao.getAllSearchPractices(searchKeyWord);
            for (BlogPractice blogPractice: list) {
                //处理贴子图片临时链接
                blogPractice.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        if(list.isEmpty()){
            list = blogPracticeDao.getByType(type);
            for (BlogPractice blogPractice: list) {
                blogPractice.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        for (BlogPractice blogPractice: list) {
            blogPractice.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }

    @Override
    public Result getSearchAgrees(String searchKeyWord, Short type, Short blogType) {
        List<BlogAgree> list = searchAgreeGetsMap.get(blogType).apply(searchKeyWord, type);
        if (type == 5){
            list = searchAllAgreeGetsMap.get(blogType).apply(searchKeyWord);
            for (BlogAgree blogAgree: list) {
                //处理贴子图片临时链接
                blogAgree.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        if(list.isEmpty()){
            list = typeAgreeGetsMap.get(blogType).apply(type);
            for (BlogAgree blogAgree: list) {
                blogAgree.handlerImgs();
            }
            return Result.ok(list,((Integer)list.size()).longValue());
        }
        for (BlogAgree blogAgree: list) {
            blogAgree.handlerImgs();
        }
        //返回结果，以及长度
        return Result.ok(list,((Integer)list.size()).longValue());
    }
}
